import { app, BrowserWindow, desktopCapturer, dialog, globalShortcut, ipcMain, screen, systemPreferences } from 'electron'
import { fileURLToPath } from 'node:url'
import path from 'node:path'
import { createRequire } from 'node:module'
import { writeFileSync } from 'fs'

const require = createRequire(import.meta.url)

const mouseEvents = require('global-mouse-events')
const { GlobalKeyboardListener } = require('node-global-key-listener')

const __dirname = path.dirname(fileURLToPath(import.meta.url))
global.__dirname = __dirname

let mainWindow: BrowserWindow | null = null
let loginWindow: BrowserWindow | null = null
let shortcutWindow: BrowserWindow | null = null
let firstPoint: Electron.Point | null = null
let keyListener
let altPressed = false
let token: string | null = null
let conversationId: number | null = null

process.env.APP_ROOT = path.join(__dirname, '..')
export const VITE_DEV_SERVER_URL = process.env['VITE_DEV_SERVER_URL']
export const MAIN_DIST = path.join(process.env.APP_ROOT, 'dist-electron')
export const RENDERER_DIST = path.join(process.env.APP_ROOT, 'dist')
process.env.VITE_PUBLIC = VITE_DEV_SERVER_URL ? path.join(process.env.APP_ROOT, 'public') : RENDERER_DIST

function createLoginWindow() {
  loginWindow = new BrowserWindow({
    width: 860,
    height: 650,
    icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'),
    webPreferences: {
      preload: path.join(__dirname, 'preload.mjs'),
      webSecurity: false
    }
  })
  loginWindow.removeMenu()

  if (VITE_DEV_SERVER_URL) {
    loginWindow.loadURL(VITE_DEV_SERVER_URL)
  } else {
    loginWindow.loadFile(path.join(RENDERER_DIST, 'index.html'))
  }

  // 开发环境下打开开发者工具
  if (VITE_DEV_SERVER_URL) {
    loginWindow.webContents.openDevTools({ mode: 'detach' })
  }
}

function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 450,
    height: 530,
    icon: path.join(process.env.VITE_PUBLIC, 'electron-vite.svg'),
    webPreferences: {
      preload: path.join(__dirname, 'preload.mjs')
    }
  })
  mainWindow.removeMenu()

  if (VITE_DEV_SERVER_URL) {
    mainWindow.loadURL(VITE_DEV_SERVER_URL + 'start')
  } else {
    mainWindow.loadFile(path.join(RENDERER_DIST, 'index.html'))
  }
  mainWindow.webContents.openDevTools({ mode: 'detach' })
}

function createShortcutWindow() {
  shortcutWindow = new BrowserWindow({
    width: 530,
    height: 700,
    webPreferences: {
      preload: path.join(__dirname, 'preload.mjs')
    }
  })
  shortcutWindow.removeMenu()

  if (VITE_DEV_SERVER_URL) {
    shortcutWindow.loadURL(VITE_DEV_SERVER_URL + 'shortcut')
  } else {
    shortcutWindow.loadFile(path.join(RENDERER_DIST, 'index.html'))
  }
}

ipcMain.handle('open-shortcut', () => {
  createShortcutWindow()
})

ipcMain.handle('open-main', () => {
  if (loginWindow && !loginWindow.isDestroyed()) {
    loginWindow.close()
  }
  createMainWindow()
})

ipcMain.handle('cancel-capture', () => {
  cancelCapture()
})

ipcMain.handle('get-cursor-position', () => {
  return screen.getCursorScreenPoint()
})

ipcMain.handle('request-permissions', async () => {
  // macOS 权限请求
  if (process.platform === 'darwin') {
    const status = systemPreferences.getMediaAccessStatus('screen')
    if (status !== 'granted') {
      await systemPreferences.askForMediaAccess('screen')
    }
  }
  return true
})

async function captureScreenNative(rect: Electron.Rectangle): Promise<Buffer> {
  try {
    // 获取包含指定区域的屏幕
    const displays = screen.getAllDisplays()
    let targetDisplay = screen.getDisplayMatching(rect)

    if (!targetDisplay) {
      targetDisplay = screen.getPrimaryDisplay()
    }

    console.log('目标显示器信息:', {
      bounds: targetDisplay.bounds,
      scaleFactor: targetDisplay.scaleFactor,
      size: targetDisplay.size,
      workAreaSize: targetDisplay.workAreaSize
    })

    // 使用实际显示器的完整分辨率，考虑缩放因子
    const actualWidth = Math.floor(targetDisplay.bounds.width * targetDisplay.scaleFactor)
    const actualHeight = Math.floor(targetDisplay.bounds.height * targetDisplay.scaleFactor)

    console.log(`请求截图尺寸: ${actualWidth}x${actualHeight}`)

    const sources = await desktopCapturer.getSources({
      types: ['screen'],
      thumbnailSize: {
        width: actualWidth,
        height: actualHeight
      }
    })

    if (sources.length === 0) {
      throw new Error('无法获取屏幕源')
    }

    // 查找对应的屏幕源
    let targetSource = sources[0] // 默认使用第一个

    // 如果有多个显示器，尝试匹配正确的屏幕
    if (displays.length > 1) {
      // 根据显示器的位置和大小来匹配
      for (let i = 0; i < sources.length; i++) {
        const source = sources[i]
        // 可以通过源的名称或其他属性来匹配，这里使用索引
        const display = displays[i]
        if (display && display.id === targetDisplay.id) {
          targetSource = source
          break
        }
      }
    }

    // 获取全屏截图
    const fullScreenshot = targetSource.thumbnail
    const screenshotSize = fullScreenshot.getSize()

    console.log('实际截图尺寸:', screenshotSize)
    console.log('目标区域:', rect)

    // 计算缩放比例
    const scaleX = screenshotSize.width / targetDisplay.bounds.width
    const scaleY = screenshotSize.height / targetDisplay.bounds.height

    console.log(`缩放比例: scaleX=${scaleX}, scaleY=${scaleY}`)

    // 计算相对于显示器的坐标，并应用缩放
    const relativeRect = {
      x: Math.max(0, Math.floor((rect.x - targetDisplay.bounds.x) * scaleX)),
      y: Math.max(0, Math.floor((rect.y - targetDisplay.bounds.y) * scaleY)),
      width: Math.min(Math.floor(rect.width * scaleX), screenshotSize.width),
      height: Math.min(Math.floor(rect.height * scaleY), screenshotSize.height)
    }

    console.log('计算后的裁剪区域:', relativeRect)

    // 确保裁剪区域有效
    if (relativeRect.width <= 0 || relativeRect.height <= 0) {
      throw new Error(`无效的裁剪区域: ${JSON.stringify(relativeRect)}`)
    }

    // 裁剪图片
    const croppedImage = fullScreenshot.crop(relativeRect)

    return croppedImage.toJPEG(85)
  } catch (error) {
    console.error('原生截图失败:', error)
    throw error
  }
}

async function captureAndUpload(rect: Electron.Rectangle) {
  const captureRect = {
    x: rect.width < 0 ? rect.x + rect.width : rect.x,
    y: rect.height < 0 ? rect.y + rect.height : rect.y,
    width: Math.abs(rect.width),
    height: Math.abs(rect.height)
  }

  // 避免0尺寸的截图
  if (captureRect.width === 0 || captureRect.height === 0) {
    console.log('截图区域尺寸为0，已取消。')
    return
  }

  await new Promise(resolve => setTimeout(resolve, 200))

  try {
    console.log(`准备截图区域: x=${captureRect.x}, y=${captureRect.y}, width=${captureRect.width}, height=${captureRect.height}`)

    // 使用原生 API 截图
    const jpgBuffer = await captureScreenNative(captureRect)
    writeFileSync('pic.jpg', jpgBuffer)

    // console.log(`准备上传 ${jpgBuffer.length} 字节的图片...`)
    // const uploadUrl = '/app-api/written-exam/upload-files'
    // const form = new FormData()
    // form.append('files', jpgBuffer, {
    //   filename: `screenshot-${Date.now()}.jpg`,
    //   contentType: 'image/jpeg'
    // })
    // form.append('conversationId', id)
    //
    // const response = await axios.post(uploadUrl, form, {
    //   headers: { ...form }
    // })
    //
    // console.log('上传成功:', response.data)
    // mainWindow?.webContents.send('upload-success', response.data)

  } catch (error) {
    console.error('截图或上传失败:', error)
    // @ts-ignore
    mainWindow?.webContents.send('upload-error', error.message)
  } finally {
    // 任务结束后，恢复显示主窗口
    // if (mainWindow && !mainWindow.isDestroyed()) {
    //   mainWindow.show()
    // }
  }
}

function handleCapture() {
  // 获取当前鼠标在屏幕上的绝对坐标
  const currentPoint = screen.getCursorScreenPoint()

  if (!firstPoint) {
    firstPoint = currentPoint
    console.log(`point 1: ${JSON.stringify(currentPoint)}`)
  } else {
    console.log(`point 2: ${JSON.stringify(currentPoint)}`)

    const rect = {
      x: firstPoint.x,
      y: firstPoint.y,
      width: currentPoint.x - firstPoint.x,
      height: currentPoint.y - firstPoint.y
    }

    firstPoint = null
    captureAndUpload(rect)
  }
}

function cancelCapture() {
  firstPoint = null
  globalShortcut.unregister('Escape')
  globalShortcut.unregister('Alt+Shift+A')
  mouseEvents.pauseMouseEvents()
  keyListener?.removeListener(changeAltPressed)
  mainWindow?.show()
}

function changeAltPressed(e) {
  if (e.name === 'LEFT ALT') {
    altPressed = (e.state === 'DOWN')
  }
}

async function checkAndRequestPermissions() {
  // 只在 macOS 上执行此检查
  if (process.platform !== 'darwin') {
    return true
  }

  // 1. 检查并请求"屏幕录制"权限
  const screenAccessStatus = systemPreferences.getMediaAccessStatus('screen')
  console.log(`当前屏幕录制权限状态: ${screenAccessStatus}`)
  if (screenAccessStatus !== 'granted') {
    // @ts-ignore
    const granted = await systemPreferences.askForMediaAccess('screen')
    if (!granted) {
      dialog.showErrorBox(
        '权限请求失败',
        '应用需要"屏幕录制"权限才能进行截图。请在"系统设置">"隐私与安全性">"屏幕录制"中为本应用授权。'
      )
      return false
    }
  }

  // 2. 检查"辅助功能"权限 (全局快捷键需要)
  const isAccessibilityTrusted = systemPreferences.isTrustedAccessibilityClient(true)
  console.log(`当前辅助功能权限状态: ${isAccessibilityTrusted}`)
  if (!isAccessibilityTrusted) {
    dialog.showErrorBox(
      '权限不足',
      '应用需要"辅助功能"权限才能使用全局快捷键。请在"系统设置">"隐私与安全性">"辅助功能"中为本应用授权。'
    )
    return false
  }

  return true
}

ipcMain.on('capture', () => {
  mainWindow?.hide()

  keyListener = new GlobalKeyboardListener()
  keyListener.addListener(changeAltPressed)

  let clickCount = 0, lastTs = 0

  function reset() {
    clickCount = 0
    lastTs = 0
  }

  mouseEvents.on('mousedown', event => {
    const now = Date.now()

    if (event.button === 1) {
      if (now - lastTs < 1000) clickCount++
      else clickCount = 1
      lastTs = now
      if (clickCount === 3) {
        handleCapture()
        reset()
      }
    }
    // Alt+左键
    if (altPressed && event.button === 1) {
      handleCapture()
    }
  })

  // 注册 ESC 快捷键用于取消
  globalShortcut.register('Escape', cancelCapture)

  const ret = globalShortcut.register('Alt+Shift+A', handleCapture)

  if (!ret) {
    console.log('全局快捷键 Alt+Shift+A 注册失败')
  }
})

app.whenReady().then(async () => {
  const hasPermissions = await checkAndRequestPermissions()
  if (!hasPermissions) {
    return
  }

  createLoginWindow()
})

app.on('will-quit', () => {
  // 确保应用退出时注销所有快捷键
  globalShortcut.unregisterAll()
})

app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) {
    createMainWindow()
  }
})

app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    // app.quit()
    // mainWindow = null
  }
})

app.on('will-quit', () => {
  // 注销所有快捷键
  globalShortcut.unregisterAll()
})